package com.ego.product.web;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.TypeReference;
import com.ego.common.constant.MemberConstant;
import com.ego.common.constant.SystemConstant;
import com.ego.common.util.Result;
import com.ego.common.vo.member.MemberVo;
import com.ego.common.vo.product.CartVo;
import com.ego.product.feign.MemberFeign;
import com.ego.product.feign.ThirdPartyFeign;
import com.ego.product.service.CartService;
import com.ego.product.vo.member.UserLoginVo;
import com.ego.product.vo.member.UserRegisterVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @program: ego
 * @description: 登录
 * @author: KamTang
 * @create: 2022-12-12 10:58
 **/
@Controller
@Slf4j
public class LoginController {

    /**
     * 同一手机号获取验证码间隔时间
     */
    private static final Long RETRY_TIME = 60000L;

    @Autowired
    private ThirdPartyFeign thirdPartyFeign;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private MemberFeign memberFeign;
    @Autowired
    private CartService cartService;

    /**
     * 发送验证码
     */
    @GetMapping("/code")
    @ResponseBody
    public Result sendCode(@RequestParam("phone") String phone) {
        // TODO 接口防刷
        String cacheKey = MemberConstant.CODE_CACHE_PREFIX + phone;
        String codeCache = stringRedisTemplate.opsForValue().get(cacheKey);
        if (!StringUtils.isEmpty(codeCache)) {
            // 获取时间戳
            long timestamp = Long.parseLong(codeCache.split(SystemConstant.SPLIT_SYMBOL)[1]);
            // 60s内不能重复发送验证码
            if (System.currentTimeMillis() - timestamp < RETRY_TIME) {
                return Result.error(SystemConstant.Status.SMS_CODE_EXCEPTION.getCode(), SystemConstant.Status.SMS_CODE_EXCEPTION.getMsg());
            }
        } else {
            // 验证码有效时间
            Result result = thirdPartyFeign.sendCode(phone, RandomUtil.randomNumbers(6));
            if (result.getCode() != SystemConstant.Status.SUCCESS.getCode()) {
                return Result.error();
            }
            // 10min有效时间
            String code = RandomUtil.randomNumbers(6) + SystemConstant.SPLIT_SYMBOL + System.currentTimeMillis();
            stringRedisTemplate.opsForValue().set(cacheKey, code, 10, TimeUnit.MINUTES);
        }
        return Result.ok();
    }

    /**
     * 注册
     * BindingResult：校验结果
     */
    @PostMapping("/registering")
    @ResponseBody
    public Result register(@Valid @RequestBody UserRegisterVo user, BindingResult bindingResult) {
        // 如果校验有异常，就转发至注册页
        if (bindingResult.hasErrors()) {
            return Result.error(SystemConstant.Status.VALID_EXCEPTION.getCode(), SystemConstant.Status.VALID_EXCEPTION.getMsg());
        }
        // 校验验证码
        String cacheKey = MemberConstant.CODE_CACHE_PREFIX + user.getPhone();
        String codeCache = stringRedisTemplate.opsForValue().get(cacheKey);
        if (StringUtils.isNotEmpty(codeCache)
                && codeCache.split(SystemConstant.SPLIT_SYMBOL)[0].equals(user.getCode())) {
            // 删除验证码
            stringRedisTemplate.delete(cacheKey);
            // 开始注册
            return memberFeign.register(user);
        } else {
            return Result.error();
        }
    }

    @PostMapping("/logging")
    @ResponseBody
    public Result login(@Valid @RequestBody UserLoginVo login, HttpSession session) {
        Result result = memberFeign.login(login);
        if (result.getCode() == SystemConstant.Status.SUCCESS.getCode()) {
            MemberVo member = result.getData(MemberConstant.LOGGED_USER, new TypeReference<MemberVo>() {
            });
            // 购物车中的商品数量(临时+登录)
            Integer goodNumInCart = (Integer) session.getAttribute("goodNumInCart");
            List<CartVo.CartItem> cartItems = cartService.getCurrentUserCartItem(member.getId());
            for (CartVo.CartItem cartItem : cartItems) {
                goodNumInCart += cartItem.getCount();
            }
            member.setGoodNumInCart(goodNumInCart);
            session.setAttribute(MemberConstant.LOGGED_USER, member);
            return Result.ok();
        } else {
            return Result.error();
        }
    }

    @GetMapping("/login")
    public String loginPage(HttpSession session) {
        if (ObjectUtils.isNotEmpty(session.getAttribute(MemberConstant.LOGGED_USER))) {
            return "redirect:http://egomall.shop";
        } else {
            return "login";
        }
    }

}
